﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using CiStatus.CiStatusAddIn.Logic;
using CiStatus.CiStatusAddIn.Logic.Exceptions;
using CiStatus.CiStatusAddIn.Logic.PluginInterfaces;
using CiStatus.CiStatusAddIn.Logic.Status;
using CiStatus.CiStatusAddIn.ViewModels;
using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Project = CiStatus.CiStatusAddIn.Logic.Project;

namespace CiStatus.CiStatusAddIn.Views.ToolWindowViews
{
    /// <summary>
    /// Interaction logic for MyControl.xaml
    /// </summary>
    public partial class CiStatusView : UserControl, IDisposable
    {
        private RefreshPump _refreshPump;

        public CiStatusView()
        {
            OptionsPage.SettingsChanged += OptionsPageSettingsChanged;
            InitializeComponent();
            try
            {
                KickRefreshPump();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            
        }

        private void KickRefreshPump()
        {
            var dte = Package.GetGlobalService(typeof(SDTE)) as DTE;
            var properties = dte.Properties["CiStatus", "Custom"];

            var resolver = new SettingsResolver(properties, new SettingsFormatter());
            var settings = resolver.Settings;
            var pluginFinder = new PluginFinder(resolver.PluginPath);
            var pluginFactories = pluginFinder.LoadPluginFactories();
            var list = new List<IProject>();

            foreach (var setting in settings)
            {
                ICiPoller poller;
                IStatus status;
                StatusDetails details;

                try
                {
                    var factory = pluginFactories.First(p => p.Name == setting.Key.Value);
                    poller = factory.CreatePoller(setting.Value);
                    poller.Connect();
                    details = new StatusDetails { Message = "Offline" };
                    status = new StatusOffline(details);
                }
                catch (CreatePollerException cpe)
                {
                    poller = new ExceptionPoller(cpe);
                    details = new StatusDetails { Message = cpe.Message };
                    status = new StatusBadSettings(details);
                }

            	var project = new Project(new RefreshCiStatus(poller, status), poller.Parameters);
//					new Setting(poller.Parameters["Project"], poller.Parameters["Server"], poller.Parameters["Link"]));
                list.Add(project);
            }

            _refreshPump = new RefreshPump(resolver.PollingFrequency, list);
            DataContext = new CiStatusViewModel(_refreshPump);
        }

        void OptionsPageSettingsChanged(object sender, EventArgs args)
        {
            if(_refreshPump != null)
                _refreshPump.Dispose();
            KickRefreshPump();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!disposing) return;

            OptionsPage.SettingsChanged -= OptionsPageSettingsChanged;
        }
    }
}